﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using PmSoft.Core.Domain;
using System.Net;

namespace PmSoft.Web.Abstractions.Auditing;

public class HttpContextClientInfoProvider : IClientInfoProvider
{
	public string BrowserInfo => GetBrowserInfo() ?? string.Empty;

	public string ClientIpAddress => GetClientIpAddress();

	public string ComputerName => GetComputerName();

	private ILogger _logger { get; set; }

	private readonly IHttpContextAccessor _httpContextAccessor;

	/// <summary>
	/// Creates a new <see cref="HttpContextClientInfoProvider"/>.
	/// </summary>
	public HttpContextClientInfoProvider(ILogger<HttpContextClientInfoProvider> logger, IHttpContextAccessor httpContextAccessor)
	{
		_httpContextAccessor = httpContextAccessor;

		_logger = logger;
	}

	protected virtual string? GetBrowserInfo()
	{
		var httpContext = _httpContextAccessor.HttpContext;
		return httpContext?.Request?.Headers?["User-Agent"];
	}

	protected virtual string GetClientIpAddress()
	{
		try
		{
			var httpContext = _httpContextAccessor.HttpContext;
			if (httpContext == null)
			{
				_logger.LogWarning("HttpContext 未初始化，无法获取客户端 IP。");
				return string.Empty;
			}

			// 检查 X-Forwarded-For 请求头，获取代理传递的客户端 IP
			var forwardedFor = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
			if (!string.IsNullOrEmpty(forwardedFor))
			{
				// X-Forwarded-For 可能包含多个 IP（客户端IP, 代理1, 代理2...），取第一个
				var ipList = forwardedFor.Split(',', StringSplitOptions.RemoveEmptyEntries);
				var clientIp = ipList.FirstOrDefault()?.Trim();

				if (!string.IsNullOrEmpty(clientIp) && IPAddress.TryParse(clientIp, out var ipAddress))
				{
					// 确保返回 IPv4 地址
					if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
					{
						return ipAddress.ToString();
					}
					else if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
					{
						// 如果是 IPv6，尝试映射到 IPv4（仅适用于映射地址）
						if (ipAddress.IsIPv4MappedToIPv6)
						{
							return ipAddress.MapToIPv4().ToString();
						}
						_logger.LogWarning($"客户端 IP {clientIp} 是 IPv6 格式，无法转换为 IPv4。");
						return string.Empty;
					}
				}

				_logger.LogWarning($"X-Forwarded-For 头中的 IP {clientIp} 无效。");
				return string.Empty;
			}

			// 如果没有 X-Forwarded-For，尝试从 Connection 获取
			var remoteIp = httpContext.Connection.RemoteIpAddress;
			if (remoteIp != null)
			{
				if (remoteIp.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
				{
					return remoteIp.ToString();
				}
				else if (remoteIp.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
				{
					if (remoteIp.IsIPv4MappedToIPv6)
					{
						return remoteIp.MapToIPv4().ToString();
					}
					_logger.LogWarning($"RemoteIpAddress {remoteIp} 是 IPv6 格式，无法转换为 IPv4。");
					return string.Empty;
				}
			}

			_logger.LogWarning("无法从 Connection.RemoteIpAddress 获取有效的 IPv4 地址。");
			return string.Empty;
		}
		catch (Exception ex)
		{
			_logger.LogWarning(ex, "获取客户端 IP 地址时发生异常。");
			return string.Empty;
		}

	}

	protected virtual string GetComputerName()
	{
		return string.Empty;
	}
}
